package com.android.multiplesmart.websocket;

import static android.app.Notification.VISIBILITY_PUBLIC;

import static com.android.multiplesmart.activity.SelectLanguageActivitys.*;

import android.annotation.SuppressLint;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.PowerManager;
import android.provider.Settings;
import android.util.Log;

import androidx.core.app.NotificationCompat;

import com.android.multiplesmart.DemoApplication;
import com.android.multiplesmart.activity.BaseActivity;
import com.android.multiplesmart.activity.SelectLanguageActivitys;

import com.android.multiplesmart.bean.MainPauseTeachingBean;
import com.android.multiplesmart.utils.HandlersUtils;
import com.android.multiplesmart.utils.WebSocketChecker;
import com.schillerchina.baselibrary.R;

import com.schillerchina.baselibrary.bean.CurrencyBean;
import com.schillerchina.baselibrary.constans.AppConstants;
import com.schillerchina.baselibrary.utils.ActivityUtils;
import com.schillerchina.baselibrary.utils.GsonUtil;
import com.schillerchina.baselibrary.utils.Pref;

import org.java_websocket.WebSocket;
import org.java_websocket.enums.ReadyState;
import org.java_websocket.handshake.ServerHandshake;

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URI;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;


/**
 * @author zhangzhiguo
 * @date 2019-08-01 09:27
 * @Description: JWebSocketClientService
 */

public class JWebSocketClientService extends Service {
    public JWebSocketClient client;
    private JWebSocketClientBinder mBinder = new JWebSocketClientBinder();
    private final static int GRAY_SERVICE_ID = 1001;
    private int  stopState=0;
    //灰色保活
    public static class GrayInnerService extends Service {

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
//            startForeground(GRAY_SERVICE_ID, new Notification());
            stopForeground(true);
            stopSelf();
            return super.onStartCommand(intent, flags, startId);
        }

        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }


    }

    PowerManager.WakeLock wakeLock;//锁屏唤醒

    //获取电源锁，保持该服务在屏幕熄灭时仍然获取CPU时，保持运行
    @SuppressLint("InvalidWakeLockTag")
    private void acquireWakeLock() {
        if (null == wakeLock) {
            PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
            wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "PostLocationService");
            if (null != wakeLock) {
                wakeLock.acquire();
            }
        }
    }

    //用于Activity和service通讯
    public class JWebSocketClientBinder extends Binder {
        public JWebSocketClientService getService() {
            return JWebSocketClientService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    public void onCreate() {
        super.onCreate();

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //初始化websocket
        Log.e("MainTestActivity", "服务被启动");

        startTask();
        //设置service为前台服务，提高优先级
        if (Build.VERSION.SDK_INT < 18) {
            //Android4.3以下 ，隐藏Notification上的图标
            startForeground(GRAY_SERVICE_ID, new Notification());
        } else if (Build.VERSION.SDK_INT > 18 && Build.VERSION.SDK_INT < 25) {
            //Android4.3 - Android7.0，隐藏Notification上的图标
            Intent innerIntent = new Intent(this, GrayInnerService.class);
            startService(innerIntent);
            startForeground(GRAY_SERVICE_ID, new Notification());
        } else {
            //Android7.0以上app启动后通知栏会出现一条"正在运行"的通知

//            NotificationCompat notificationBuilder = new NotificationCompat.Builder(JWebSocketClientService.this, GRAY_SERVICE_ID);
//            Notification notification = notificationBuilder.setOngoing(true)
//                    .setSmallIcon(R.mipmap.ic_launcher)
//                    .setPriority(PRIORITY_MIN)
//                    .setCategory(Notification.CATEGORY_SERVICE)
//                    .build();

//            startForeground(GRAY_SERVICE_ID, notification);

        }

        acquireWakeLock();
        return START_STICKY;
    }

    CompositeDisposable disposables = new CompositeDisposable();
    Timer timer;
    private  void startTasks(){
        TimerTask task = new TimerTask(){

            public void run(){
                timer.cancel();
                initSocketClient();
                mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测
                //execute the task
            }
        };
        timer = new Timer();
        timer.schedule(task, 3000);

    }
    // 开始或重新开始任务
    public    void startTask() {
//        startTasks();
        disposables.add(Observable.interval(3000, TimeUnit.MILLISECONDS)
                .subscribeOn(Schedulers.io())
                .subscribe(aLong -> {
                    String s= Pref.getString(AppConstants.WS_ADDRESS,"");
                    //ws://192.168.6.171:9102
                    String[]  s1=  s.split(":");
                    //System.out.println(s1[1].replace("//","")+"JWebSocketClientService---"+s1[2]);
//                  if (isPortOpen(s1[1].replace("//",""),Integer.parseInt(s1[2]),3000)){
//                        System.out.println("JWebSocketClientService 打开了");
//                  }else {
//                        System.out.println("JWebSocketClientService 没打开");
//                  }
                    isDomainReachable(s);
                    // 这里是你想要反复执行的代码
                })); // 打印错误
    }

    // 停止任务
    void stopTask() {
        disposables.clear(); // 清空所有订阅，停止任务
    }

    @Override
    public void onDestroy() {
        Log.e("JWebSocketClientService", "服务被销毁");
//        closeConnect();
        super.onDestroy();
    }

    public JWebSocketClientService() {
    }


    /**
     * 初始化websocket连接
     */
    int state=1;




    public static boolean isPortOpen(String ipAddress, int port, int timeout) {
        try {
            InetAddress address = InetAddress.getByName(ipAddress);
            Socket socket = new Socket(address, port);
            socket.setSoTimeout(timeout); // 设置超时时间
            return true; // 如果能够创建Socket，则端口是开放的
        } catch (IOException e) {
            return false; // 如果抛出IOException，则端口是关闭的
        }
    }

    public void isDomainReachable(String domain) {
//        System.out.println("JWebSocketClientService 打开了");
        WebSocketChecker.checkWebSocket(Pref.getString(AppConstants.WS_ADDRESS,""), new WebSocketChecker.WebSocketCheckCallback() {
            @Override
            public void onSuccess() {
                // 域名通畅
                stopTask();
                startTasks();
            }

            @Override
            public void onFailure(Throwable t) {
                // 域名不通或者连接失败
                System.out.println("JWebSocketClientService连接失败");
            }
        });
    }

    public int   getStopState(){
        return stopState;
    }

    private void initSocketClient() {
        System.out.println(Pref.getString(AppConstants.WS_ADDRESS,"")+"JWebSocketClientService");
        if (client!=null){
            client.close();
            client = null;
        }
        String id= getAndroidId(getApplicationContext());
        System.out.println(id+"获取android id"+Pref.getString(AppConstants.WS_ADDRESS,"")+"/"+id);
        URI uri;
        uri= URI.create(Pref.getString(AppConstants.WS_ADDRESS,"")+"/"+id);
//        9f39d20b01589f2c

        client = new JWebSocketClient(uri) {
            @Override
            public void onMessage(String message) {
                DemoApplication.getHandlerUtils().saveCrashInfo2File("onMessage:  "+message);
                Log.e("JWebSocketClientService", "收到的消息：" + message);
                Intent intent = new Intent();
//              intent.setAction("com.xch.servicecallback.content");
                CurrencyBean c=GsonUtil.GsonToBean(message, CurrencyBean.class);
                if (c.getCmd().equals("ClassroomInfo")){//PC端主动推送教室和语种数据: PC(教师端) → Android(学生端)
                    intent.setAction(AppConstants.WEBSOCKET_SNED_MESSAGE_ACTION);
                }else if (c.getCmd().equals("BeginTeaching")){//PC主动推送开始授课信号
                    intent.setAction(AppConstants.WEBSOCKET_TEACHING_ACTION);
                    stopState=1;
                }else if (c.getCmd().equals("PauseTeaching")){//PC主动推送暂停授课信号
                    intent.setAction(AppConstants.WEBSOCKET_STOP_TEACHING_ACTION);
                    MainPauseTeachingBean mainPauseTeachingBean=GsonUtil.GsonToBean(message, MainPauseTeachingBean.class);
                    stopState=2;
                }else if (c.getCmd().equals("FinalTeaching")){//PC主动推送结束授课信号
                    intent.setAction(AppConstants.WEBSOCKET_COLSE_TEACHING_ACTION);
                }else if (c.getCmd().equals("LiveSpeech")){//PC端主动推送教师发言内容
                    intent.setAction(AppConstants.WEBSOCKET_LIVESPEECH_TEACHING_ACTION);
                }else if (c.getCmd().equals("PageInfo")){//PC端主动推送教师发言内容
                    intent.setAction(AppConstants.WEBSOCKET_SY_TEACHING_ACTION);
                }else if (c.getCmd().equals("LangCode")){//PC端主动推送教师发言内容
                    intent.setAction(AppConstants.WEBSOCKET_SY_LANGUAGE_ACTION);
                }else if (c.getCmd().equals("TeacherSpeeching")){
                    intent.setAction(AppConstants.WEBSOCKET_SY_LANGUAGE_SPEEHING);
                }else if (c.getCmd().equals("ResponseSpeech")){
                    intent.setAction(AppConstants.WEBSOCKET_SY_LANGUAGE_ResponseSpeech);
                }else if (c.getCmd().equals("StudentSpeeching")){
                    intent.setAction(AppConstants.WEBSOCKET_SY_LANGUAGE_StudentSpeeching);
                }
                intent.putExtra("message", message);
                sendBroadcast(intent);
//              checkLockAndShowNotification(message);
            }
            @Override
            public void onOpen(ServerHandshake handshakedata) {
//              super.onOpen(handshakedata);
                conect(AppConstants.onOpen,"连接成功");
                BaseActivity baseActivity=  (BaseActivity) DemoApplication.getCurrentActivity();
                String name="";
                if (baseActivity!=null){
                    name=baseActivity.getPackageName();
                }
                DemoApplication.getHandlerUtils().saveCrashInfo2File("onOpen:  "+"连接成功"+"-----"+name+"----"+Pref.getString(AppConstants.WS_ADDRESS,"")+"----"+id);
                Log.e("JWebSocketClientService", "websocket连接成功");
            }

            @Override
            public void onClose(int code, String reason, boolean remote) {
                super.onClose(code, reason, remote);
                DemoApplication.getHandlerUtils().saveCrashInfo2File("onClose:  "+"关闭了"+"---"+code);
                if (client != null) {
                    client.close();
                    client = null;
                }
//              conect(AppConstants.colse,"连接成功");
                BaseActivity baseActivity=  (BaseActivity) DemoApplication.getCurrentActivity();
                if (baseActivity instanceof SelectLanguageActivitys){
                    SelectLanguageActivitys.activitys.start();
                }else{
                    baseActivity.finish();
                    SelectLanguageActivitys.activitys.start();
                }
                startTask();
                System.out.println("JWebSocketClientService onClose执行一次");
            }


            @Override
            public void onError(Exception ex) {
                super.onError(ex);
                DemoApplication.getHandlerUtils().saveCrashInfo2File("onError:  "+"出现异常"+ex.toString());
            }
        };
        connect();
    }

    /**
     * 连接websocket
     */
    private void connect() {
        new Thread() {
            @Override
            public void run() {
                //System.out.println(Pref.getString(AppConstants.WS_ADDRESS,"")+"JWebSocketClientService111");
                if (client == null) {
                    return;
                }
                if (!client.isOpen()) {
                    if (client.getReadyState().equals(ReadyState.NOT_YET_CONNECTED)) {
                        try {
                            try {
                                DemoApplication.getHandlerUtils().saveCrashInfo2File("connectBlocking:  "+"重连了");
                                client.connectBlocking();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                                DemoApplication.getHandlerUtils().saveCrashInfo2File("connectBlocking:  "+"重连了"+e.toString());
                            }
                        } catch (IllegalStateException e) {

                        }
                    }
                }
            }
        }.start();

    }

    /**
     * 发送消息
     *
     * @param msg
     */
    public boolean sendMsg(String msg,OnCallBack onCallBack) {
        if (null != client) {
            Log.e("JWebSocketClientService", "发送的消息：" + msg);
            if (!client.isClosed()){
                client.send(msg);
                onCallBack.onSend("1");
                return false;
            }else {
                onCallBack.onSend("2");
                return true;
            }
        }else {

            return  true;
        }

    }


    public  interface  OnCallBack{
        void  onSend(String state);
    }

    /**
     * 断开连接
     */
    public void closeConnect() {
        try {
            if (null != client) {
                client.close();
                client=null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            client = null;
        }
    }


//    -----------------------------------消息通知--------------------------------------------------------

    /**
     * 检查锁屏状态，如果锁屏先点亮屏幕
     *
     * @param content
     */
    private void checkLockAndShowNotification(String content) {
        //管理锁屏的一个服务
        KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
        if (km.inKeyguardRestrictedInputMode()) {//锁屏
            //获取电源管理器对象
            PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
            if (!pm.isScreenOn()) {
                @SuppressLint("InvalidWakeLockTag") PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP |
                        PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bright");
                wl.acquire();  //点亮屏幕
                wl.release();  //任务结束后释放
            }
            sendNotification(content);
        } else {
            sendNotification(content);
        }
    }

    /**
     * 发送通知
     *
     * @param content
     */
    private void sendNotification(String content) {
        Intent intent = new Intent();
        intent.setClass(this, BaseActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        NotificationManager notifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        @SuppressLint("WrongConstant") Notification notification = new NotificationCompat.Builder(this)
                .setAutoCancel(true)
                // 设置该通知优先级
                .setPriority(Notification.PRIORITY_MAX)
                .setSmallIcon(R.drawable.icon)
                .setContentTitle("服务器")
                .setContentText(content)
                .setVisibility(VISIBILITY_PUBLIC)
                .setWhen(System.currentTimeMillis())
                // 向通知添加声音、闪灯和振动效果
                .setDefaults(Notification.DEFAULT_VIBRATE | Notification.DEFAULT_ALL | Notification.DEFAULT_SOUND)
                .setContentIntent(pendingIntent)
                .build();
        notifyManager.notify(1, notification);//id要保证唯一
    }


    //    -------------------------------------websocket心跳检测------------------------------------------------
    private static final long HEART_BEAT_RATE = 5000;//每隔1秒进行一次对长连接的心跳检测
    private Handler mHandler = new Handler();
    private int number=1;
    private Runnable heartBeatRunnable = new Runnable() {
        @Override
        public void run() {
            if (client != null) {
                Log.e("JWebSocketClientService", client.isClosed()+"");
                if (client.isClosed() && states==1) {//首页的话一直重连
//                    Log.e("JWebSocketClientService", client.isClosed()+"");
                    reconnectWs();
                }else if (client.isClosed() && states==2){//翻译页面就重连两次
//                    BaseActivity baseActivity=  (BaseActivity) DemoApplication.getCurrentActivity();
//                    if (baseActivity instanceof SelectLanguageActivitys){
//                        activitys.start();
//                    }else {
//                        baseActivity.finish();
//                        activitys.start();
//                    }
                    Log.e("JWebSocketClientService", "跳出");
                }else {

                }
            }
            //每隔一定的时间，对长连接进行一次心跳检测
//            mHandler.postDelayed(this, HEART_BEAT_RATE);
        }
    };


    int states;
    public void setStates(int states){
        this.states=states;
    }
    private  void conect(String key,String value){
        Intent intent = new Intent();
        intent.setAction(key);
        intent.putExtra("message", value);
        sendBroadcast(intent);
    }

    public  String getAndroidId(Context context) {
        return Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
    }

    /**
     * 开启重连
     */
    private void reconnectWs() {
        mHandler.removeCallbacks(heartBeatRunnable);
    }
}
